package sg.edu.nus.iss.stockex;

import java.util.LinkedList;

public class SlidingWindow {

	LinkedList<TimestampPriceDataPoint> currentWindow;
	
	long windowSize;
	long slideIncrement;
	long currentTime;
	long sampleSize;
	
	public SlidingWindow( long windowSizeInMS, long slideIncrement, long sample_size ) {
	
		this.windowSize = windowSizeInMS;
		this.slideIncrement = slideIncrement;
		this.currentTime = 0;
		this.sampleSize = sample_size;
		this.currentWindow = new LinkedList<TimestampPriceDataPoint>();
		
	}
	
	public long GetWindowStepSize() {
		
		return this.slideIncrement;
		
	}
	
	public long GetWindowSize() {
		return this.windowSize;
	}
	
	
	public boolean WindowIsFull() {
		
		if ( this.GetWindowDelta() >= this.windowSize ) {
			return true;
		}
		
		return false;
		
	}
	
	public long GetWindowDelta() {
		
		if ( this.currentWindow.size() > 0 ) {
			//long a = this.currentWindow.getLast().getLongTradeDate();
			//long b = this.currentWindow.getFirst().getLongTradeDate();
			//long c = this.sampleSize;
			//long d = this.currentWindow.getLast().getLongTradeDate() - this.currentWindow.getFirst().getLongTradeDate() + this.sampleSize;
			return this.currentWindow.getLast().getLongTradeDate() - this.currentWindow.getFirst().getLongTradeDate() + this.sampleSize;
		}
		
		return 0;
		
	}
	
	public void AddPoint( TimestampPriceDataPoint point ) throws Exception {

		// look at back of window
		
		// if back of window is greater than this point, throw exception
		if ( this.currentWindow.size() > 0) {
			if ( point.getLongTradeDate() <= this.currentWindow.getLast().getLongTradeDate() ) {
				throw new Exception( "Point out of order!" );
			}
		}
		
		this.currentWindow.add( point );
		
	}
	
	public int GetNumberPointsInWindow() {
		
		return this.currentWindow.size();
		
	}

	/**
	 * Slide the window forward
	 * - burn off the first half of the window
	 * - still must re-add more points from the Reduce iterator
	 * @throws Exception
	 */
	public void slideWindowForward() {
		
		long currentFront = this.currentWindow.getFirst().getLongTradeDate();
		this.currentTime = currentFront + this.slideIncrement;
		
		// now burn off the tail
		
		while ( this.currentWindow.getFirst().getLongTradeDate() < this.currentTime ) {
			this.currentWindow.removeFirst();
		}				
		
	}	


	public LinkedList<TimestampPriceDataPoint> GetCurrentWindow() {
		
		return this.currentWindow;
		
	}

	
}
